#ifndef _SGF_MATH_H_
#define _SGF_MATH_H_

#include <cmath>
#include "Type.h"

namespace SGF
{
	template <class Real>
	class Math
	{
	public:
		static Real ACos(Real value);
		static Real ASin(Real value);
		static Real ATan(Real value);
		static Real Ceil(Real value);
		static Real Cos(Real value);
		static Real Exp(Real value);
		static Real FAbs(Real value);
		static Real Floor(Real value);
		static Real FMod(Real x, Real y);
		static Real Log(Real value);
		static Real Log10(Real value);
		static Real Pow(Real base, Real exponent);
		static Real Sin(Real value);
		static Real Sqr(Real value);
		static Real Sqrt(Real value);
		static Real Tan(Real value);
		static const Real PI;
		static const Real PI_2;
		static const Real PI_4;
		static const Real E;
	};
	template <class Real>
	Real64 SGF::Math<Real>::PI = 3.1415926535897932384626433832795;
	template <class Real>
	Real64 SGF::Math<Real>::PI_2 = 1.5707963267948966192313216916398;
	template <class Real>
	Real64 SGF::Math<Real>::PI_4 = 0.78539816339744830961566084581988;
	template <class Real>
	Real64 SGF::Math<Real>::E = 2.7182818284590452353602874713527;
	template <class Real>
	Real SGF::Math<Real>::ACos( Real value )
	{
		return acos(value);
	}
	template <class Real>
	Real SGF::Math<Real>::ASin( Real value )
	{
		return asin(value);
	}
	template <class Real>
	Real SGF::Math<Real>::ATan( Real value )
	{
		return atan(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Ceil( Real value )
	{
		return ceil(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Cos( Real value )
	{
		return cos(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Exp( Real value )
	{
		return exp(value);
	}
	template <class Real>
	Real SGF::Math<Real>::FAbs( Real value )
	{
		return fabs(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Floor( Real value )
	{
		return floor(value);
	}
	template <class Real>
	Real SGF::Math<Real>::FMod( Real x, Real y )
	{
		return fmod(x, y);
	}
	template <class Real>
	Real SGF::Math<Real>::Log( Real value )
	{
		return log(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Log10( Real value )
	{
		return log10(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Pow( Real base, Real exponent )
	{
		return pow(base, exponent);
	}
	template <class Real>
	Real SGF::Math<Real>::Sin( Real value )
	{
		return sin(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Sqr( Real value )
	{
		return value * value;
	}
	template <class Real>
	Real SGF::Math<Real>::Sqrt( Real value )
	{
		return sqrt(value);
	}
	template <class Real>
	Real SGF::Math<Real>::Tan( Real value )
	{
		return tan(value);
	}
}

#endif
